
#include "message_coder.h"
#include <limits>

namespace qb{
namespace proto{


Buffer::Buffer(void * data , uint32_t size)
{
    data_ = (char *)data ;
    size_ = size ;
    offset_ = 0 ;
}

void Buffer::Reset()
{
    data_ = NULL ;
    size_ = 0 ;
    offset_ = 0 ;
}

bool Buffer::check_size(size_t len) const
{
    if(offset_ + len > size_)
        return false ;
    return true ;
}

bool Buffer::PutUInt8(uint8_t val)
{
    if(check_size(1) == false)
        return false ;

    data_[offset_++] = val ;
    return true ;
}

bool Buffer::PutUInt16(uint16_t val)
{
    if(check_size(2) == false)
        return false ;

    data_[offset_++] = (uint8_t)(0xFF & (val >> 8)) ;
    data_[offset_++] = (uint8_t)(0xFF & val) ;

    return true ;
}

bool Buffer::PutUInt32(uint32_t val)
{
    if(check_size(4) == false)
        return false ;

    data_[offset_++] = (uint8_t)(0xFF & (val >> 24)) ;
    data_[offset_++] = (uint8_t)(0xFF & (val >> 16)) ;
    data_[offset_++] = (uint8_t)(0xFF & (val >> 8)) ;
    data_[offset_++] = (uint8_t)(0xFF & val) ;

    return true ;
}

bool Buffer::PutUInt64(uint64_t val)
{
    if(check_size(8) == false)
        return false ;

    uint32_t hi = (uint32_t)(val >> 32);
    uint32_t lo = (uint32_t)val;
    PutUInt32(hi);
    PutUInt32(lo);
    return true ;
}

bool Buffer::PutInt8(int8_t val)
{
    if(check_size(1) == false)
        return false ;

    if(check_size(1) == false)
        return false ;

    data_[offset_++] = (uint8_t)val ;
    return true ;

}

bool Buffer::PutInt16(int16_t val)
{
    return PutUInt16((uint16_t)val) ;
}

bool Buffer::PutInt32(int32_t val)
{
    return PutUInt32((uint32_t)val) ;
}

bool Buffer::PutInt64(int64_t val)
{
    return PutUInt64((uint64_t)val) ;
}

bool Buffer::PutFloat(float val)
{
    union {
        uint32_t i;
        float    f;
    } data;

    data.f = val;
    return PutUInt32 (data.i);
}

bool Buffer::PutDouble(double val)
{
    union {
        uint64_t i;
        double    f;
    } data;

    data.f = val;
    return PutUInt64 (data.i);
}


/*
    取值，基础类型
*/
bool Buffer::GetUInt8(uint8_t& val)
{
    if(check_size(1) == false)
        return false ;

    val = (uint8_t) data_[offset_++] ;
    return true ;
}

bool Buffer::GetUInt16(uint16_t& val)
{
    if(check_size(2) == false)
        return false ;

    uint16_t hi = (uint8_t) data_[offset_++] ;
    hi = hi << 8 ;
    hi |= (uint8_t)data_[offset_++] ;
    val = hi ;
    return true ;
}

bool Buffer::GetUInt32(uint32_t& val)
{
    if(check_size(4) == false)
        return false ;

    uint32_t a = (uint8_t)data_[offset_++] ;
    uint32_t b = (uint8_t)data_[offset_++] ;
    uint32_t c = (uint8_t)data_[offset_++] ;
    uint32_t d = (uint8_t)data_[offset_++] ;

    val = a << 24 ;
    val |= b << 16 ;
    val |= c << 8 ;
    val |= d ;

    return true ;
}

bool Buffer::GetUInt64(uint64_t& val)
{
    if(check_size(8) == false)
        return false ;

    uint32_t hi = 0 ;
    GetUInt32(hi) ;
    uint32_t lo = 0 ;
    GetUInt32(lo) ;

    val = hi ;
    val = (val << 32) | lo ;
    return true ;
}

bool Buffer::GetInt8(int8_t& val)
{
    return GetUInt8((uint8_t&)val) ;
}

bool Buffer::GetInt16(int16_t& val)
{
    return GetUInt16((uint16_t&)val) ;
}

bool Buffer::GetInt32(int32_t& val)
{
    return GetUInt32((uint32_t&)val) ;
}

bool Buffer::GetInt64(int64_t& val)
{
    return GetUInt64((uint64_t&)val) ;
}

bool Buffer::GetFloat(float& val)
{
    union {
        uint32_t i;
        float    f;
    } data ;
    if(GetUInt32(data.i) == false)
        return false ;

    val = data.f ;
    return true ;
}

bool Buffer::GetDouble(double& val)
{
    union {
        uint64_t i;
        double    f;
    } data ;

    if(GetUInt64(data.i) == false)
        return false ;

    val = data.f ;
    return true ;
}


bool Buffer::PutString(const std::string& val)
{
    return PutRaw(val.c_str() , val.length()) ;
}

bool Buffer::PutShortString(const std::string& val) 
{
    return PutShortRaw(val.c_str() , val.length()) ;
}

bool Buffer::PutLongString(const std::string& val)
{
    return PutLongRaw(val.c_str() , val.length()) ;
}

bool Buffer::PutRaw(const void * data , size_t size) 
{
    if(size > std::numeric_limits<uint8_t>::max())
        return false ;

    uint8_t len = (uint8_t)size ;
    if(check_size(size + 1) == false)
        return false ;

    PutUInt8(len) ;
    if(len > 0)
    {
        memcpy(data_ + offset_ , data , len) ;
        offset_ += size ;
    }
    else
    {
        //如果size == 0 ，不放内容
    }
    return true ;
}

bool Buffer::PutShortRaw(const void * data , size_t size)
{
    if(size > std::numeric_limits<uint16_t>::max())
        return false ;

    uint16_t len = (uint16_t)size ;
    if(check_size(size + 2) == false)
        return false ;

    PutUInt16(len) ;
    if(len > 0)
    {
        memcpy(data_ + offset_ , data , len) ;
        offset_ += size ;
    }
    return true ;
}

bool Buffer::PutLongRaw(const void * data , size_t size)
{
    if(check_size(size + 4) == false)
        return false ;

    PutUInt32(size) ;
    if(size > 0)
    {
        memcpy(data_ + offset_ , data , size) ;
        offset_ += size ;
    }
    return true ;
}

bool Buffer::GetString(const char *& val , size_t& size)
{
    val = NULL ;
    size = 0 ;

    if(check_size(1) == false)
        return false ;

    uint8_t len = 0 ;
    GetUInt8(len) ;

    if(check_size(len) == false)
    {
        //回滚1个字节
        offset_ -= 1;
        return false ;
    }

    val = data_ + offset_ ;
    size = len ;
    offset_ += len ;
    return true ;
}

bool Buffer::GetShortString(const char *& val , size_t& size)
{
    val = NULL ;
    size = 0 ;

    if(check_size(2) == false)
        return false ;

    uint16_t len = 0 ;
    GetUInt16(len) ;

    if(check_size(len) == false)
    {
        //回滚1个字节
        offset_ -= 2;
        return false ;
    }

    val = data_ + offset_ ;
    size = len ;
    offset_ += len ;
    return true ;
}

bool Buffer::GetLongString(const char *& val , size_t& size)
{
    val = NULL ;
    size = 0 ;

    if(check_size(4) == false)
        return false ;

    uint32_t len = 0 ;
    GetUInt32(len) ;

    if(check_size(len) == false)
    {
        //回滚1个字节
        offset_ -= 4;
        return false ;
    }

    val = data_ + offset_ ;
    size = len ;
    offset_ += len ;
    return true ;
}

bool Buffer::GetString(std::string& val)
{
    val.clear() ;

    const char * str = NULL ;
    size_t size = 0 ;

    if(GetString(str , size) == false)
        return false ;

    val.assign(str , size) ;
    return true ;
}

bool Buffer::GetShortString(std::string& val)
{
    val.clear() ;

    const char * str = NULL ;
    size_t size = 0 ;

    if(GetShortString(str , size) == false)
        return false ;

    val.assign(str , size) ;
    return true ;
}


bool Buffer::GetLongString(std::string& val)
{
    val.clear() ;

    const char * str = NULL ;
    size_t size = 0 ;

    if(GetLongString(str , size) == false)
        return false ;

    val.assign(str , size) ;
    return true ;
}

bool Buffer::GetRaw(const void *& data , size_t& size)
{
    data = NULL ;
    size = 0 ;

    uint8_t len = 0 ;
    if(GetUInt8(len) == false)
        return false ;

    if(check_size(len) == false)
    {
        //回滚1个字节
        offset_ -= 1;
        return false ;
    }

    data = (const uint8_t *)data_ + offset_ ;
    size = len ;
    offset_ += len ;

    return true ;
}

bool Buffer::GetShortRaw(const void *& data , size_t& size)
{
    data = NULL ;
    size = 0 ;

    uint16_t len = 0 ;
    if(GetUInt16(len) == false)
        return false ;

    if(check_size(len) == false)
    {
        //回滚1个字节
        offset_ -= 2;
        return false ;
    }

    data = data_ + offset_ ;
    size = len ;
    offset_ += len ;

    return true ;
}

bool Buffer::GetLongRaw(const void *& data , size_t& size)
{
    data = NULL ;
    size = 0 ;

    uint32_t len = 0 ;
    if(GetUInt32(len) == false)
        return false ;

    if(check_size(len) == false)
    {
        //回滚1个字节
        offset_ -= 4;
        return false ;
    }

    data = data_ + offset_ ;
    size = len ;
    offset_ += len ;

    return true ;
}

Encoder::Encoder(Buffer& buffer) 
:buffer_(buffer)
{
    //
}


bool Encoder::ToQpidType(const Variant& var , uint8_t& type) 
{
    type = 0 ;

    uint8_t qpid_type = 0 ;
    switch(var.Type)
    {
    case Variant::VAR_BOOL : qpid_type = 0x08 ; break ;

    /*
    case Variant::VAR_INT8 : qpid_type = 0x01 ; break ;
    case Variant::VAR_UINT8 : qpid_type = 0x02 ; break ;
    */
    /*
        qpid在实现的时候，有个BUG，int8_t和uint8_t的typecode偏移了一位，
        见Codecs.cpp的Variant toVariant(boost::shared_ptr<FieldValue> in)
    */
    case Variant::VAR_INT8 : qpid_type = 0x02 ; break ;
    case Variant::VAR_UINT8 : qpid_type = 0x03 ; break ;


    case Variant::VAR_INT16 : qpid_type = 0x11 ; break ;
    case Variant::VAR_UINT16 : qpid_type = 0x12 ; break ;    
    case Variant::VAR_INT32 : qpid_type = 0x21 ; break ;
    case Variant::VAR_UINT32 : qpid_type = 0x22 ; break ;    
    case Variant::VAR_INT64 : qpid_type = 0x31 ; break ;
    case Variant::VAR_UINT64 : qpid_type = 0x32 ; break ;    

    case Variant::VAR_FLOAT : qpid_type = 0x23 ; break ;
    case Variant::VAR_DOUBLE : qpid_type = 0x33 ; break ;    

    case Variant::VAR_STRING : 
        /*
        if(var.Length < 256)
            qpid_type = 0x85 ;      //str8
        else if(var.Length < 65536)
            qpid_type = 0x95 ;      //str16
        else
            return false ;
        break ;
        */
        /*
            字符串类型的值，都使用2个字节表示长度，默认情况下，不指定编码格式encode，qpid都将按vbin[16/32]处理，见            
            qpid项目的Codecs.cpp的toFieldValue函数以及convertString函数。我们强制指定为utf8编码，都使用2个字节的长度。
            不支持4个字节长度
        */
        qpid_type = 0x95 ;
        break ;

    case Variant::VAR_RAW : 
        if(var.Length < 256)
            qpid_type = 0x80 ;      //vbin8
        else if(var.Length < 65536)
            qpid_type = 0x90 ;      //vbin16
        else
            qpid_type = 0xa0 ;      //vbin32

        break ;

    case Variant::VAR_MAP :  qpid_type = 0xa8 ; break ;
    case Variant::VAR_LIST : qpid_type = 0xa9 ; break ;
	case Variant::VAR_TABLE:
	{
		// 将table当成raw
		const VariantTable* table = NULL;
		var.RefTable(table);
		int size = table ? table->encode() : 0;
		if (size < 256)
			qpid_type = 0x80;      //vbin8
		else if (size < 65536)
			qpid_type = 0x90;      //vbin16
		else
			qpid_type = 0xa0;      //vbin32
	}
    case Variant::VAR_VOID : qpid_type = 0xf0 ; break ;
    default : break ;
    }

    if(qpid_type == 0)
        return false ;
    
    type = qpid_type ;
    return true ;
}


bool Encoder::Encode(const Variant& var) 
{
    uint8_t qpid_type = 0 ;
    if(ToQpidType(var , qpid_type) == false || buffer_.PutUInt8(qpid_type) == false)
        return false ;

    bool result = false ;
    switch(var.Type)
    {
    case Variant::VAR_BOOL : result = EncodeBool(var) ; break ;

     case Variant::VAR_INT8 : result = EncodeInt8(var) ; break ;
    case Variant::VAR_UINT8 : result = EncodeUInt8(var) ; break ;
    case Variant::VAR_INT16 : result = EncodeInt16(var) ; break ;
    case Variant::VAR_UINT16 : result = EncodeUInt16(var) ; break ;
    case Variant::VAR_INT32 : result = EncodeInt32(var) ; break ;
    case Variant::VAR_UINT32 : result = EncodeUInt32(var) ; break ;
    case Variant::VAR_INT64 : result = EncodeInt64(var) ; break ;
    case Variant::VAR_UINT64 : result = EncodeUInt64(var) ; break ;

    case Variant::VAR_FLOAT : result = EncodeFloat(var) ; break ;
    case Variant::VAR_DOUBLE : result = EncodeDouble(var) ; break ;        

    case Variant::VAR_STRING : result = EncodeString(var.Data.str , var.Length) ; break ;
    case Variant::VAR_RAW : result = EncodeRaw(var.Data.raw , var.Length) ; break ;        

    case Variant::VAR_MAP : result = EncodeMap(var) ; break ;
    case Variant::VAR_LIST : result = EncodeList(var) ; break ;    
	case Variant::VAR_TABLE: result = EncodeTable(var); break;
    case Variant::VAR_VOID : result = EncodeVoid(var) ; break ;    
    default: break ;
    }

    if(result == false)
        buffer_.Shrink(1) ;

    return result ;
}


bool Encoder::EncodeBool(bool value) 
{
    return buffer_.PutUInt8((uint8_t)value) ;    
}


bool Encoder::EncodeInt8(int8_t value) 
{
    return buffer_.PutInt8(value) ;
}

bool Encoder::EncodeUInt8(uint8_t value) 
{
    return buffer_.PutUInt8(value) ;
}

bool Encoder::EncodeInt16(int16_t value) 
{
    return buffer_.PutInt16(value) ;
}

bool Encoder::EncodeUInt16(uint16_t value) 
{
    return buffer_.PutUInt16(value) ;
}

bool Encoder::EncodeInt32(int32_t value) 
{
    return buffer_.PutInt32(value) ;
}

bool Encoder::EncodeUInt32(uint32_t value) 
{
    return buffer_.PutUInt32(value) ; 
}

bool Encoder::EncodeInt64(int64_t value) 
{
    return buffer_.PutInt64(value) ;
}

bool Encoder::EncodeUInt64(uint64_t value) 
{
    return buffer_.PutUInt64(value) ;
}


bool Encoder::EncodeFloat(float value) 
{
    return buffer_.PutFloat(value) ; 
}

bool Encoder::EncodeDouble(double value) 
{
    return buffer_.PutDouble(value) ;
}


bool Encoder::EncodeString(const char * value , size_t size) 
{
    /*
        通过跟踪qpid的代码，对于map来说，有key，有value。
        Key总是以1个字节的长度编码，但是value只支持2个字节和4个字节，
        不支持1个字节。另外字符串的编码，是不带结束符的。     

        为了c类的字符串访问安全，ss::proto::Variant会在字符串后面自动添加'\0'，必须去掉长度。
        在qpid中，字符串和RAW是在一起的，除非指定utf8编码格式，否则都是以Raw的方式传输。
        纯粹的字符串，只支持2个字节的长度。
    */
    uint32_t Length = size ;
    if(Length > 0)
    {
        if(value[Length - 1] == '\0')
            --Length ;
    }

    if(Length >= 65535)
        return false ;

    if(buffer_.PutShortRaw(value , Length) == false)
    {
        buffer_.Shrink(2) ;
        return false ;
    }
    else
        return true ;
}

bool Encoder::EncodeRaw(const void * value , size_t size) 
{
    int bytes = 0 ;
    if(size < 256)
        bytes = 1 ;
    else if(size < 65536)
        bytes = 2 ;
    else 
        bytes = 4 ;

    bool result = false ;
    switch(bytes)
    {
    case 1 : 
        result = buffer_.PutRaw(value , size) ;
        break ;
    case 2 :
        result = buffer_.PutShortRaw(value , size) ;
        break ;
    case 4 :
        result = buffer_.PutLongRaw(value, size) ;
        break ;
    }

    if(result == false)
        return false ;
    else
        return true ;
}


bool Encoder::EncodeMap(const Variant::Map& value) 
{
    /*
        计算出来的size = type[1] + size[4] + count[4] + cont
    */
    uint32_t size = CalcSizeMap(value) ;
    if(size <= 8 || buffer_.CheckSize(size - 1) == false)        //编码类型字段，少一个字节
        return false ;

    uint32_t count = value.size() ;
    uint32_t offset = buffer_.Offset() ;

    buffer_.PutUInt32(size - 5) ;
    buffer_.PutUInt32(count) ;

    //没有数据，不再编码。
    if(count == 0)
        return true ;

    bool result = true ;
    for(Variant::Map::const_iterator citer = value.begin() ; citer != value.end() ; ++citer)
    {
        const Variant * var = citer->second ;
        if(var == NULL)
        {
            result = false ;
            break ;
        }

        buffer_.PutString(citer->first) ;        //名字
        if((result = Encode(*var)) == false)
            break ;
    }

    if(result == false)
        buffer_.Offset(offset) ;

    return result ;
}

bool Encoder::EncodeTable(const Variant::Table& value)
{
	/*
		将table的内容编码成raw
		然后用EncodeRaw再次将raw编码
	*/
	int size = value.encode();
	const char* data = value.c_str();
	return EncodeRaw(data, size);
}
bool Encoder::EncodeList(const Variant::List& value) 
{
    /*
        计算出来的size = type + size + count + cont
    */
    uint32_t size = CalcSizeList(value) ;
    if(size <= 8 || buffer_.CheckSize(size - 1) == false)
        return false ;

    uint32_t count = value.size() ;
    uint32_t offset = buffer_.Offset() ;

    buffer_.PutUInt32(size - 5) ;
    buffer_.PutUInt32(count) ;

    if(count == 0)
        return true ;

    bool result = true ;
    for(Variant::List::const_iterator citer = value.begin() ; citer != value.end() ; ++citer)
    {
        if((result = Encode(*citer)) == false)
            break ;
    }

    if(result == false)
        buffer_.Offset(offset) ;

    return result ;
}

bool Encoder::EncodeVoid(const Variant& var)
{
    return true ;
}

int Encoder::CalcSize(const Variant& var) 
{
    switch(var.Type)
    {
    case Variant::VAR_BOOL : return CalcSizeBool(var) ;

    case Variant::VAR_INT8 : return CalcSizeInt8(var) ;
    case Variant::VAR_UINT8 : return CalcSizeUInt8(var) ;
    case Variant::VAR_INT16 : return CalcSizeInt16(var) ;
    case Variant::VAR_UINT16 : return CalcSizeUInt16(var) ;
    case Variant::VAR_INT32 : return CalcSizeInt32(var) ;
    case Variant::VAR_UINT32 : return CalcSizeUInt32(var) ;
    case Variant::VAR_INT64 : return CalcSizeInt64(var) ;
    case Variant::VAR_UINT64 : return CalcSizeUInt64(var) ;

    case Variant::VAR_FLOAT : return CalcSizeFloat(var) ;
    case Variant::VAR_DOUBLE : return CalcSizeDouble(var) ;        

    case Variant::VAR_STRING : return CalcSizeString(var.Data.str , var.Length) ;
    case Variant::VAR_RAW : return CalcSizeRaw(var.Data.raw , var.Length) ;        

    case Variant::VAR_MAP : return CalcSizeMap(var) ;
    case Variant::VAR_LIST : return CalcSizeList(var) ; 
	case Variant::VAR_TABLE:{
		const VariantTable* table = NULL;
		var.RefTable(table);
		int size = table ? table->encode() : 0;
		return size;
	}
    case Variant::VAR_VOID : return CalcSizeVoid(var) ;
    default: break ;
    }

    return 0 ;
}

int Encoder::CalcSizeBool(bool value) 
{
    return 2 ;
}


int Encoder::CalcSizeInt8(int8_t value) 
{
    return 2 ;
}

int Encoder::CalcSizeUInt8(uint8_t value) 
{
    return 2 ;
}

int Encoder::CalcSizeInt16(int16_t value) 
{
    return 3 ;
}

int Encoder::CalcSizeUInt16(uint16_t value) 
{
    return 3 ;
}

int Encoder::CalcSizeInt32(int32_t value) 
{
    return 5 ;
}

int Encoder::CalcSizeUInt32(uint32_t value) 
{
    return 5 ;
}

int Encoder::CalcSizeInt64(int64_t value) 
{
    return 9 ;
}

int Encoder::CalcSizeUInt64(uint64_t value) 
{
    return 9 ;
}


int Encoder::CalcSizeFloat(float value) 
{
    return 5 ;
}

int Encoder::CalcSizeDouble(double value) 
{
    return 9 ;
}



int Encoder::CalcSizeString(const char * value , size_t size) 
{
    if(value == NULL)
        size = 0 ;

    if(size > 0)
    {
        if(value[size - 1] == '\0')
            --size ;                //不包含结束符'\0'
    }

    if(size >= 65535)
        return 0 ;

    return (1 + 2 + (int)size) ;
}

int Encoder::CalcSizeRaw(const void * value , size_t size) 
{
    if(value == NULL)
        size = 0 ;

    int bytes = 0 ;
    if(size < 256)
        bytes = 1 ;
    else if(size < 65536)
        bytes = 2 ;
    else
        bytes = 4 ;

    return (1 + bytes + (int)size) ;
}


int Encoder::CalcSizeMap(const Variant::Map& value) 
{
    int size = 8 ;  // size [4] + count[4]

    int len = 0 ;
    for(Variant::Map::const_iterator citer = value.begin() ; citer != value.end() ; ++citer)
    {
        //key           key都是使用str8
        len += 1 ;
        char * name = citer->first ;
        if(name != NULL)
        {
            len += ::strlen(name) ;
        }

        //fields，具体的长度由每个字段决定，可能是定长的，也可能是变长的
        const Variant * var = citer->second ;
        int vsize = 0 ;
        if(var != NULL)
        {
            vsize = Encoder::CalcSize(*var) ;
        }
        /*
            计算失败
        */
        if(vsize == 0)
            return 0 ;

        len += vsize ;
    }

    return 1 + size + len ;    
}

int Encoder::CalcSizeList(const Variant::List& value) 
{
    int size = 8 ;  // size [4] + count[4]

    int len = 0 ;
    for(Variant::List::const_iterator citer = value.begin() ; citer != value.end() ; ++citer)
    {
        //items，具体长度，由每个元素自己决定，可能是定长的，也可能是变长的
        int vsize = Encoder::CalcSize(*citer) ;
        if(vsize == 0)
            return 0 ;

        len += vsize ;
    }

    return 1 + size + len ;
}

int Encoder::CalcSizeVoid(const Variant& var)
{
    return 1 ;      //只有类型字段，没有值
}


Decoder::Decoder(Buffer& buffer)
:buffer_(buffer)
{
    //
}

bool Decoder::DecodeType(uint8_t& type) 
{
    type = 0 ;
    if(buffer_.GetUInt8(type) == false)
        return false ;
    else
        return true ;
}

bool Decoder::Decode(Variant& var)
{
    uint8_t type = 0;
    if(DecodeType(type) == false)
        return false ;

    bool result = false ;
    switch(type)
    {
    case 0x08 : result = DecodeBool(var) ; break ;   //bool

    /*
    case 0x01 : result =  DecodeInt8(var) ; break ;  //int8
    case 0x02 : result =  DecodeUInt8(var) ; break ; //uint8
    */
    case 0x02 : result =  DecodeInt8(var) ; break ;  //int8
    case 0x03 : result =  DecodeUInt8(var) ; break ; //uint8

    case 0x11 : result =  DecodeInt16(var) ; break ; //int16 
    case 0x12 : result =  DecodeUInt16(var) ; break ; //uint16
    case 0x21 : result =  DecodeInt32(var) ; break ; //int32
    case 0x22 : result =  DecodeUInt32(var) ; break ; //uint32    
    case 0x31 : result =  DecodeInt64(var) ; break ; //int64
    case 0x32 : result =  DecodeUInt64(var) ; break ; //uint64

    case 0x23 : result =  DecodeFloat(var) ; break ; //float
    case 0x33 : result =  DecodeDouble(var) ; break ;//double

    case 0x84 :
    case 0x85 : result =  DecodeString(var) ; break ;//str8 , str8-latin
    case 0x94 :
    case 0x95 : result =  DecodeShortString(var) ; break ;//str16 , str16-latin

    case 0x80 : result =  DecodeRaw(var) ; break ;       //vbin8
    case 0x90 : result =  DecodeShortRaw(var) ; break ;  //vbin16
    case 0xa0 : result =  DecodeLongRaw(var) ; break ;   //vbin32

    case 0xa8 : result =  DecodeMap(var) ; break ;       //map
    case 0xa9 : result =  DecodeList(var) ; break ;       //list

    //void类型，后面没有值和类型
    case 0xf0 : result = DecodeVoid(var) ; break ;      //void

    default : break ;
    }

    if(result == false)
    {
        buffer_.Shrink(1) ;
    }

    return result ;    
}

bool Decoder::DecodeBool(Variant& var) 
{
    if(buffer_.CheckSize(1) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetUInt8(var.Data.u8)== false)
        return false ;

    var.Type = Variant::VAR_BOOL ;
    return true ;
}


bool Decoder::DecodeInt8(Variant& var) 
{
    if(buffer_.CheckSize(1) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetInt8(var.Data.i8)== false)
        return false ;

    var.Type = Variant::VAR_INT8 ;
    return true ;
}

bool Decoder::DecodeUInt8(Variant& var) 
{
    if(buffer_.CheckSize(1) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetUInt8(var.Data.u8)== false)
        return false ;

    var.Type = Variant::VAR_UINT8 ;
    return true ;
}

bool Decoder::DecodeInt16(Variant& var) 
{
    if(buffer_.CheckSize(2) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetInt16(var.Data.i16)== false)
        return false ;

    var.Type = Variant::VAR_INT16 ;
    return true ;
}

bool Decoder::DecodeUInt16(Variant& var) 
{
    if(buffer_.CheckSize(2) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetUInt16(var.Data.u16)== false)
        return false ;

    var.Type = Variant::VAR_UINT16 ;
    return true ;
}

bool Decoder::DecodeInt32(Variant& var) 
{
    if(buffer_.CheckSize(4) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetInt32(var.Data.i32)== false)
        return false ;

    var.Type = Variant::VAR_INT32 ;
    return true ;
}

bool Decoder::DecodeUInt32(Variant& var) 
{
    if(buffer_.CheckSize(4) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetUInt32(var.Data.u32)== false)
        return false ;

    var.Type = Variant::VAR_UINT32 ;
    return true ;
}

bool Decoder::DecodeInt64(Variant& var) 
{
    if(buffer_.CheckSize(8) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetInt64(var.Data.i64)== false)
        return false ;

    var.Type = Variant::VAR_INT64 ;
    return true ;
}

bool Decoder::DecodeUInt64(Variant& var) 
{
    if(buffer_.CheckSize(8) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetUInt64(var.Data.u64)== false)
        return false ;

    var.Type = Variant::VAR_UINT64 ;
    return true ;
}


bool Decoder::DecodeFloat(Variant& var) 
{
    if(buffer_.CheckSize(4) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetFloat(var.Data.f32)== false)
        return false ;

    var.Type = Variant::VAR_FLOAT ;
    return true ;
}

bool Decoder::DecodeDouble(Variant& var) 
{
    if(buffer_.CheckSize(8) == false)
        return false ;

    var.Data.val = 0 ;
    if(buffer_.GetDouble(var.Data.f64)== false)
        return false ;

    var.Type = Variant::VAR_DOUBLE ;
    return true ;
}


bool Decoder::DecodeString(Variant& var) 
{
    var.Clear() ;
    var.Type = Variant::VAR_STRING ;

    const char * str = NULL ;
    size_t size = 0 ;

    if(buffer_.GetString(str , size) == false)
        return false ;

    if(size == 0)
        return true ;

    //判断下，尾部是否为0
    size_t slen = size ;
    if(str[size - 1] != 0)
        ++slen ;  

    char * sbuf = (char *)malloc(slen) ;
    if(sbuf == NULL)
        return false ;

    memcpy(sbuf , str , size) ;
    sbuf[slen - 1] = '\0' ;

    var.Length = slen - 1;
    var.Data.str = sbuf ;
    return true ;
}

bool Decoder::DecodeShortString(Variant& var) 
{
    var.Clear() ;
    var.Type = Variant::VAR_STRING ;

    const char * str = NULL ;
    size_t size = 0 ;

    if(buffer_.GetShortString(str , size) == false)
        return false ;

    if(size == 0)
        return true ;

    //判断下，尾部是否为0
    size_t slen = size ;
    if(str[size - 1] != 0)
        ++slen ;  

    char * sbuf = (char *)malloc(slen) ;
    if(sbuf == NULL)
        return false ;

    memcpy(sbuf , str , size) ;
    sbuf[slen - 1] = '\0' ;

    var.Length = slen - 1;
    var.Data.str = sbuf ;
    return true ;
}


bool Decoder::DecodeRaw(Variant& var) 
{
    var.Clear() ;
    var.Type = Variant::VAR_RAW ;

    const void * data = NULL ;
    size_t size = 0 ;

    if(buffer_.GetRaw(data , size) == false)
        return false ;

    if(size == 0)
        return true ;

    void * raw = malloc(size) ;
    if(raw == NULL)
    {
        buffer_.Shrink(1) ;
        return false ;
    }

    memcpy(raw , data , size) ;

    var.Length = size ;
    var.Data.raw = raw ;

    return true ;
}

bool Decoder::DecodeShortRaw(Variant& var) 
{
    var.Clear() ;
    var.Type = Variant::VAR_RAW ;

    const void * data = NULL ;
    size_t size = 0 ;

    if(buffer_.GetShortRaw(data , size) == false)
        return false ;

    if(size == 0)
        return true ;

    void * raw = malloc(size) ;
    if(raw == NULL)
    {
        buffer_.Shrink(1) ;
        return false ;
    }

    memcpy(raw , data , size) ;

    var.Length = size ;
    var.Data.raw = raw ;

    return true ;
}

bool Decoder::DecodeLongRaw(Variant& var) 
{
    var.Clear() ;
    var.Type = Variant::VAR_RAW ;

    const void * data = NULL ;
    size_t size = 0 ;

    if(buffer_.GetLongRaw(data , size) == false)
        return false ;

    if(size == 0)
        return true ;

    void * raw = malloc(size) ;
    if(raw == NULL)
    {
        buffer_.Shrink(1) ;
        return false ;
    }

    memcpy(raw , data , size) ;

    var.Length = size ;
    var.Data.raw = raw ;

    return true ;
}

bool Decoder::DecodeMapDirect(Variant::Map& map)
{
    /*
        size field[4] + count field[4]
    */
    if(buffer_.CheckSize(8) == false)
        return false ;

    uint32_t size = 0 , count = 0 ;
    buffer_.GetUInt32(size) ;
    if(buffer_.CheckSize(size) == false)     //长度4个字节已经偏移了。
    {
        buffer_.Shrink(4) ;
        return false ;
    }

    buffer_.GetUInt32(count) ;

    bool result = true ;
    for(uint32_t idx = 0 ; idx < count ; ++idx)
    {
        const char * name = NULL ;
        size_t nlen = 0 ;
        if((result = buffer_.GetString(name , nlen)) == false)
            break ;

        if(name == NULL || nlen == 0)
        {
            result = false ;
            break ;
        }

        Variant* var = map.AddVariant(name , nlen) ;
        if(var == NULL)
        {
            result = false ;
            break ;
        }
        
        if((result = Decode(*var)) == false)
            break ;    
    }

    if(result == false)
    {
        map.clear() ;
        buffer_.Shrink(8) ;
        return false ;
    }

    map.item_changed_ = true ;
    return true ;
}

bool Decoder::DecodeMap(Variant& var) 
{
    Variant::Map *map = new Variant::Map() ;
    if(DecodeMapDirect(*map) == false)
    {
        delete map ;
        return false ;
    }

    var.Type = Variant::VAR_MAP ;
    var.Length = 0 ;
    var.Data.raw = map ;
    return true ;
}

bool Decoder::DecodeList(Variant& var) 
{
    /*
        size field[4] + count field[4]
    */
    if(buffer_.CheckSize(8) == false)
        return false ;

    uint32_t size = 0 , count = 0 ;
    buffer_.GetUInt32(size) ;
    if(buffer_.CheckSize(size) == false)
    {
        buffer_.Shrink(4) ;
        return false ;
    }

    buffer_.GetUInt32(count) ;

    VariantList * list = new VariantList() ;
    bool result = true ;
    for(uint32_t idx = 0 ; idx < count ; ++idx)
    {
        Variant * n = list->add_variant() ;
        if(n == NULL)
        {
            result = false ;
            break ;
        }

        if((result = Decode(*n)) == false)
            break ;    
    }

    if(result == false)
    {
        delete list ;
        buffer_.Shrink(8) ;
        return false ;
    }

    var.Type = Variant::VAR_LIST ;
    var.Length = 0 ;
    var.Data.raw = list ;
    return true ;
}

bool Decoder::DecodeVoid(Variant& var)
{
    return true ;
}



}
}
